package com.example.annealing.common.web;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Gene
 * @date 2019/4/19
 */
public class BaseController<S extends IService<T>, T, PK extends Serializable> {

    @Autowired
    protected S baseService;

    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "新增实体", notes = "新增一个实体，请查看对应实体，在body中以Json格式传输")
    public CommonResult<T> add(@Validated(Create.class) @RequestBody T t) {
        return baseService.save(t) ? CommonResult.success(t) : CommonResult.failed();
    }

    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除一个实体", notes = "删除一个实体")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "id", value = "<K>/实体的主键ID", required = true)
    })
    public CommonResult delete(@PathVariable("id") PK id) {
        return baseService.removeById(id) ? CommonResult.success() : CommonResult.failed();
    }

    @PutMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "更新实体", notes = "更新一个实体，请查看对应实体，在body中以Json格式传输")
    public CommonResult<T> update(@Validated(Update.class) @RequestBody T t) {
        return baseService.updateById(t) ? CommonResult.success() : CommonResult.failed();
    }

    @GetMapping("listPage")
    @ApiOperation(value = "分页获取实体列表", notes = "分页获取实体列表，请查看对应实体属性，参数名以实体属性为准")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页码", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "页面容量", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "descs", value = "降序排序", dataType = "String", allowMultiple = true, paramType = "query"),
            @ApiImplicitParam(name = "ascs", value = "升序排序", dataType = "String", allowMultiple = true, paramType = "query")
    })
    public CommonResult<CommonPage<T>> listByPage(T t,
                                                  @RequestParam(required = false, defaultValue = "1") Long current,
                                                  @RequestParam(required = false, defaultValue = "10") Long size,
                                                  String[] ascs,
                                                  String[] descs) {
        Page<T> page = new Page<>(current, size);
        List<OrderItem> items = new ArrayList<>();
        if (ascs != null) {
            for (String s : ascs) {
                OrderItem item = new OrderItem();
                item.setColumn(s);
                items.add(item);
            }
        }
        if (descs != null) {
            for (String s : descs) {
                OrderItem item = new OrderItem();
                item.setColumn(s);
                item.setAsc(false);
                items.add(item);
            }
        }
        page.addOrder(items);
        return CommonResult.success(CommonPage.restPage(baseService.page(page, Wrappers.lambdaQuery(t))));
    }

    @GetMapping("list")
    @ApiOperation(value = "获取全部实体", notes = "获取全部记录，请查看对应实体属性，参数名以实体属性为准")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "ascs", allowMultiple = true, value = "String/升序字段数组，对象属性驼峰改蛇形"),
            @ApiImplicitParam(paramType = "query", name = "descs", allowMultiple = true, value = "String/降序字段数组，对象属性驼峰改蛇形")
    })
    public CommonResult<List<T>> all(T t,
                                     @RequestParam(required = false) String[] ascs,
                                     @RequestParam(required = false) String[] descs) {
        QueryWrapper<T> wrapper = new QueryWrapper<>(t);
        wrapper.orderBy(ascs != null, true, ascs);
        wrapper.orderBy(descs != null, false, descs);
        return CommonResult.success(baseService.list(wrapper));
    }

    @GetMapping("one/{id}")
    @ApiOperation(value = "获取单个实体", notes = "获取单个实体，请查看对应实体属性，参数名以实体属性为准")
    public CommonResult<T> one(@PathVariable("id") PK id) {
        return CommonResult.success(baseService.getById(id));
    }

    @PostMapping(value = "/add-or-update")
    @ApiOperation(value = "新增或修改对象", notes = "根据对象主键id，新增或修改对象")
    public CommonResult<T> saveOrUpdate(@Validated @RequestBody T t) {
        return baseService.saveOrUpdate(t) ? CommonResult.success() : CommonResult.failed();
    }

    @PutMapping("/add-or-updateBatch")
    @ApiOperation(value = "批量新增或修改对象", notes = "批量根据对象主键id，新增或修改对象")
    public CommonResult saveOrUpdateBatch(@RequestBody List<T> t) {
        return baseService.saveOrUpdateBatch(t) ? CommonResult.success() : CommonResult.failed();
    }

}
